<template>
  <div class="error-boundary">
    <!-- 正常渲染子组件 -->
    <slot v-if="!hasError" />
    
    <!-- 错误状态显示 -->
    <div v-else class="error-container">
      <div class="error-content">
        <!-- 错误图标 -->
        <div class="error-icon">
          <el-icon size="64" color="#f56c6c">
            <WarningFilled />
          </el-icon>
        </div>
        
        <!-- 错误信息 -->
        <div class="error-info">
          <h3 class="error-title">系统错误</h3>
          <p class="error-message">页面渲染时发生了错误，请刷新页面重试</p>
        </div>
        
        <!-- 操作按钮 -->
        <div class="error-actions">
          <el-button 
            type="primary" 
            @click="handleRetry"
            :loading="retrying"
          >
            重试
          </el-button>
          
          <el-button 
            @click="handleReload"
            :disabled="retrying"
          >
            刷新页面
          </el-button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onErrorCaptured, onMounted } from 'vue'
import { ElMessage, ElIcon, ElButton } from 'element-plus'
import { WarningFilled } from '@element-plus/icons-vue'

// Props
const props = defineProps({
  showDetails: {
    type: Boolean,
    default: false
  },
  customTitle: {
    type: String,
    default: ''
  },
  customMessage: {
    type: String,
    default: ''
  },
  showReportButton: {
    type: Boolean,
    default: false
  },
  autoRetry: {
    type: Boolean,
    default: false
  },
  maxRetries: {
    type: Number,
    default: 3
  },
  retryDelay: {
    type: Number,
    default: 2000
  }
})

const emit = defineEmits(['error', 'retry', 'report'])

const hasError = ref(false)
const errorInfo = ref(null)
const retrying = ref(false)
const retryCount = ref(0)

// 错误捕获
onErrorCaptured((error, instance, info) => {
  console.error('ErrorBoundary caught error:', error, info)
  
  // 设置错误状态
  hasError.value = true
  errorInfo.value = {
    message: error.message || '发生了未知错误',
    originalError: error,
    timestamp: new Date().toISOString()
  }
  retryCount.value = 0
  
  // 发出错误事件
  emit('error', errorInfo.value)
  
  // 阻止错误继续向上传播
  return false
})

// 重试处理
const handleRetry = async () => {
  if (retrying.value) return
  
  retrying.value = true
  retryCount.value++
  
  try {
    // 等待一段时间后重置错误状态
    await new Promise(resolve => setTimeout(resolve, 1000))
    
    // 重置错误状态
    hasError.value = false
    errorInfo.value = null
    
    // 发出重试事件
    emit('retry', retryCount.value)
    
    ElMessage.success('重试成功')
  } catch (error) {
    console.error('Retry failed:', error)
    ElMessage.error('重试失败，请稍后再试')
  } finally {
    retrying.value = false
  }
}

// 刷新页面
const handleReload = () => {
  window.location.reload()
}

// 重置错误状态的方法（供外部调用）
const reset = () => {
  hasError.value = false
  errorInfo.value = null
  retryCount.value = 0
}

// 暴露方法给父组件
defineExpose({
  reset,
  hasError: () => hasError.value,
  errorInfo: () => errorInfo.value
})

onMounted(() => {
  // 监听全局错误事件
  window.addEventListener('error', (event) => {
    if (!hasError.value) {
      onErrorCaptured(event.error || new Error(event.message), null, 'global error')
    }
  })
  
  window.addEventListener('unhandledrejection', (event) => {
    if (!hasError.value) {
      onErrorCaptured(event.reason, null, 'unhandled promise rejection')
    }
  })
})
</script>

<style scoped>
.error-boundary {
  width: 100%;
  height: 100%;
}

.error-container {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 400px;
  padding: 40px 20px;
  background: #fafafa;
}

.error-content {
  text-align: center;
  max-width: 600px;
  width: 100%;
}

.error-icon {
  margin-bottom: 24px;
}

.error-info {
  margin-bottom: 32px;
}

.error-title {
  font-size: 24px;
  font-weight: 600;
  color: #303133;
  margin: 0 0 16px 0;
}

.error-message {
  font-size: 16px;
  color: #606266;
  margin: 0 0 16px 0;
  line-height: 1.5;
}

.error-details {
  margin-top: 16px;
  text-align: left;
}

.error-details summary {
  cursor: pointer;
  font-weight: 500;
  color: #409eff;
  margin-bottom: 8px;
}

.error-stack {
  background: #f5f5f5;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  padding: 12px;
  font-size: 12px;
  color: #606266;
  white-space: pre-wrap;
  word-break: break-all;
  max-height: 200px;
  overflow-y: auto;
}

.error-actions {
  display: flex;
  gap: 12px;
  justify-content: center;
  margin-bottom: 24px;
}

.error-suggestions {
  text-align: left;
  background: #f0f9ff;
  border: 1px solid #b3d8ff;
  border-radius: 8px;
  padding: 16px;
}

.error-suggestions h4 {
  margin: 0 0 12px 0;
  font-size: 14px;
  font-weight: 600;
  color: #303133;
}

.error-suggestions ul {
  margin: 0;
  padding-left: 20px;
}

.error-suggestions li {
  margin-bottom: 4px;
  font-size: 14px;
  color: #606266;
  line-height: 1.4;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .error-container {
    padding: 20px 16px;
    min-height: 300px;
  }
  
  .error-title {
    font-size: 20px;
  }
  
  .error-message {
    font-size: 14px;
  }
  
  .error-actions {
    flex-direction: column;
    align-items: center;
  }
  
  .error-actions .el-button {
    width: 100%;
    max-width: 200px;
  }
}
</style>